package com.flywen.generator;

import com.flywen.generator.common.DBName;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class ParserInfo {
    private String tableName;
    private String tableComment;
    private String sequenceName;
    private String daoPackage;
    private String daoName;
    private String daoVarName;
    private String modelPackage;
    private String modelName;
    private String servicePackage;
    private String serviceImplPackage;
    private String keyColName;
    private String subPackage;
    private List<Field> fields = new ArrayList();
    private Field primarykeyFields;

    public ParserInfo(Connection connection, String parentPackageName, String tableName, String sequenceName) throws Exception {
        this.daoPackage = parentPackageName + ".dao";
        this.servicePackage = parentPackageName + ".service";
        this.serviceImplPackage = parentPackageName + ".service.impl";
        this.modelPackage = parentPackageName + ".model";
        this.tableName = tableName;
        if (sequenceName == null) {
            sequenceName = tableName + "_S";
        }

        this.sequenceName = sequenceName;
        String javaName = Utils.getJavaName(tableName);
        this.daoName = javaName + "Dao";
        this.daoVarName = this.daoName.substring(0, 1).toLowerCase() + this.daoName.substring(1);
        this.modelName = javaName;
        this.queryDBForTable(connection, tableName);
    }

    public ParserInfo(Connection connection, String parentPackageName, String tableName, String sequenceName, String modelPackageName) throws Exception {
        this.daoPackage = parentPackageName + ".dao";
        this.servicePackage = parentPackageName + ".service";
        this.serviceImplPackage = parentPackageName + ".service.impl";
        this.modelPackage = modelPackageName + ".model";
        this.tableName = tableName;
        if (sequenceName == null) {
            sequenceName = tableName + "_S";
        }

        this.sequenceName = sequenceName;
        String javaName = Utils.getJavaName(tableName);
        this.daoName = javaName + "Dao";
        this.daoVarName = this.daoName.substring(0, 1).toLowerCase() + this.daoName.substring(1);
        this.modelName = javaName;
        this.queryDBForTable(connection, tableName);
    }

    private void queryDBForTable(Connection connection, String tableName) throws SQLException {
        Statement statement = connection.createStatement();
        ResultSet rs = null;
        if (DBName.MYSQL.equals(Generator.dbName)){
            //查询schema中所有的表
            rs = statement.executeQuery("select table_comment from Information_schema.tables WHERE table_name = '" + tableName.toUpperCase() + "'" + "AND TABLE_SCHEMA = '" + Generator.properties.getProperty("table_schema") + "'");
        }else if (DBName.ORACLE.equals(Generator.dbName)){
            //查询命名空间中所有的表
            rs = statement.executeQuery("select * from user_tables WHERE table_name = '" + tableName.toUpperCase() + "'" + "AND TABLESPACE_NAME = '" + Generator.properties.getProperty("tablespace_name") + "'");
        }
        if (rs.next()) {
            this.tableComment = rs.getString(1);
        }

        statement.close();
        rs.close();
        statement = connection.createStatement();
        //查询主键名称
        if (DBName.MYSQL.equals(Generator.dbName)){
            rs = statement.executeQuery("SELECT col.column_name FROM Information_schema.COLUMNS col WHERE col.table_name = '" + tableName.toUpperCase() + "' AND col.column_key = 'PRI'" + "AND TABLE_SCHEMA = '" + Generator.properties.getProperty("table_schema") + "'");
        }else if (DBName.ORACLE.equals(Generator.dbName)){
            //TODO oracle
            String sql = "SELECT column_name FROM user_cons_columns U, user_constraints c WHERE U.table_name = '"+tableName.toUpperCase()+"' AND U .constraint_name = c.index_name AND c.constraint_type = 'P'";
            rs = statement.executeQuery(sql);
        }
        if (rs.next()) {
            this.keyColName = rs.getString(1);
        }

        statement.close();
        rs.close();
        statement = connection.createStatement();
        if (DBName.MYSQL.equals(Generator.dbName)){
            rs = statement.executeQuery("SELECT col.column_name, col.data_type, col.column_comment, col.column_key, col.numeric_precision, col.numeric_scale FROM Information_schema.COLUMNS col WHERE col.table_name = '" + tableName.toUpperCase() + "'" + "AND TABLE_SCHEMA = '" + Generator.properties.getProperty("table_schema") + "'");
            while(rs.next()) {
                String columnName = rs.getString(1);
                String type = rs.getString(2).toUpperCase();
                String description = rs.getString(3);
                String key = rs.getString(4);
                int precision = rs.getInt(5);
                int scale = rs.getInt(6);
                if ("PRI".equalsIgnoreCase(key)) {
                    this.primarykeyFields = new Field(columnName, type, Utils.getPropertyKeyByColumnName(columnName), true, precision, scale);
                    this.primarykeyFields.setFieldName(columnName);
                    this.primarykeyFields.setDescription(description);
                } else {
                    Field field = new Field(columnName, type, Utils.getPropertyKeyByColumnName(columnName), false, precision, scale);
                    field.setFieldName(columnName);
                    field.setDescription(description);
                    this.fields.add(field);
                }
            }
        }else if (DBName.ORACLE.equals(Generator.dbName)){
            //TODO oracle
            String sql = "SELECT A .COLUMN_NAME,A .DATA_TYPE, U .comments, A.DATA_PRECISION, A.DATA_SCALE FROM user_tab_columns A, user_col_comments U WHERE U .TABLE_NAME = A .TABLE_NAME AND A.COLUMN_NAME = U.COLUMN_NAME AND A .TABLE_NAME = '"+tableName.toUpperCase()+"'";
            rs = statement.executeQuery(sql);
            while(rs.next()) {
                //列名称
                String columnName = rs.getString(1);
                //类型
                String type = rs.getString(2).toUpperCase();
                //注释
                String description = rs.getString(3);
                //长度
                int precision = rs.getInt(4);
                //精度
                int scale = rs.getInt(5);
                if (columnName.equalsIgnoreCase(this.keyColName)) {
                    //主键
                    this.primarykeyFields = new Field(columnName, type, Utils.getPropertyKeyByColumnName(columnName), true, precision, scale);
                    this.primarykeyFields.setDescription(description);
                } else {
                    Field field = new Field(columnName, type, Utils.getPropertyKeyByColumnName(columnName), false, precision, scale);
                    field.setDescription(description);
                    this.fields.add(field);
                }
            }
        }


        rs.close();
        statement.close();
    }

    public String getDaoName() {
        return this.daoName;
    }

    public String getDaoPackage() {
        return this.daoPackage;
    }

    public List<Field> getFields() {
        return this.fields;
    }

    public String getModelName() {
        return this.modelName;
    }

    public String getModelPackage() {
        return this.modelPackage;
    }

    public String getSequenceName() {
        return this.sequenceName;
    }

    public String getTableComment() {
        return this.tableComment;
    }

    public String getTableName() {
        return this.tableName;
    }

    public void setDaoName(String daoName) {
        this.daoName = daoName;
    }

    public void setDaoPackage(String daoPackage) {
        this.daoPackage = daoPackage;
    }

    public void setFields(List<Field> fields) {
        this.fields = fields;
    }

    public void setModelName(String modelName) {
        this.modelName = modelName;
    }

    public void setModelPackage(String modelPackage) {
        this.modelPackage = modelPackage;
    }

    public void setSequenceName(String sequenceName) {
        this.sequenceName = sequenceName;
    }

    public void setTableComment(String tableComment) {
        this.tableComment = tableComment;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public String getKeyColName() {
        return this.keyColName;
    }

    public void setKeyColName(String keyColName) {
        this.keyColName = keyColName;
    }

    public String getSubPackage() {
        return this.subPackage;
    }

    public void setSubPackage(String subPackage) {
        this.subPackage = subPackage;
    }

    public Field getPrimarykeyFields() {
        return this.primarykeyFields;
    }

    public void setPrimarykeyFields(Field primarykeyFields) {
        this.primarykeyFields = primarykeyFields;
    }

    public String getServicePackage() {
        return this.servicePackage;
    }

    public void setServicePackage(String servicePackage) {
        this.servicePackage = servicePackage;
    }

    public String getServiceImplPackage() {
        return this.serviceImplPackage;
    }

    public void setServiceImplPackage(String serviceImplPackage) {
        this.serviceImplPackage = serviceImplPackage;
    }

    public String getDaoVarName() {
        return this.daoVarName;
    }

    public void setDaoVarName(String daoVarName) {
        this.daoVarName = daoVarName;
    }
}